﻿using LJ.Abstractions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LJ.EventBus.HornedSerpent.Internal;

public class EventBusHandlerInvoker(IDependencyInjectionFactory dependencyInjectionFactory, IEventBusHandlerManager eventBusHandlerManager) : IEventBusHandlerInvoker
{
    private readonly IDependencyInjectionFactory _dependencyInjectionFactory = dependencyInjectionFactory;
    private readonly IEventBusHandlerManager _eventBusHandlerManager = eventBusHandlerManager;


    public async Task InvokeAsync(EventBusMessage message)
    {
        var eventBusHandlerDescriptor = _eventBusHandlerManager.GetEventBusHandlerDescriptor(message.GetName());

        using var serviceScope = _dependencyInjectionFactory.CreateScope();
        var serviceProvider = serviceScope.ServiceProvider;

        var eventHandlerInstance =
           serviceProvider.GetRequiredService(eventBusHandlerDescriptor.EventBusHandlerType);

        var method = eventBusHandlerDescriptor.EventBusHandlerType.GetMethod("ExecuteAsync",
                [eventBusHandlerDescriptor.EventDataType, typeof(IDictionary<string, string>)]);

        var task = (Task?)method!.Invoke(eventHandlerInstance, [message.Value, message.Headers]);
        await task!;
    }
}
